package com.tian.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.tian.common.CommonResult;
import com.tian.common.PageResult;
import com.tian.dto.coupon.CouponAddReqDto;
import com.tian.dto.coupon.CouponPageReqDto;
import com.tian.dto.coupon.CouponRespDto;
import com.tian.dto.coupon.CouponUpdateReqDto;
import com.tian.entity.Coupon;
import com.tian.enums.*;
import com.tian.mapper.CouponMapper;
import com.tian.service.CouponService;
import com.tian.util.RedisConstantPre;
import lombok.extern.slf4j.Slf4j;
/*import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;*/
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * {@code @description:} 优惠券
 *
 * @author tianwc 公众号：Java后端技术全栈
 * 在线刷题 1200+java面试题和1000+篇技术文章：<a href="https://woaijava.cc/">博客地址</a>
 * {@code @date:} 2024/1/23 9:58
 * {@code @version:} 1.0
 */
@Slf4j
@Service
public class CouponServiceImpl implements CouponService {
    @Resource
    private CouponMapper couponMapper;
    @Resource
    private RedissonClient redissonClient;

    @Override
    public CommonResult<Boolean> add(CouponAddReqDto couponAddReqDto) {
        Coupon coupon = new Coupon();
        BeanUtils.copyProperties(couponAddReqDto, coupon);
        coupon.setStatus(0);
        couponMapper.insert(coupon);
        RBucket<Coupon> bucket = redissonClient.getBucket(RedisConstantPre.COUPON_CONDITION_PRE + coupon.getId());
        //防止缓存中意缓存了空对象的场景
        if (bucket.get() != null) {
            bucket.delete();
        }
        bucket.set(coupon);
        return CommonResult.success(Boolean.TRUE);
    }

    @Override
    public CommonResult<Boolean> update(CouponUpdateReqDto couponUpdateReqDto) {
        Coupon coupon = new Coupon();
        BeanUtils.copyProperties(couponUpdateReqDto, coupon);
        int update = couponMapper.updateByPrimaryKey(coupon);
        return CommonResult.success(update != 0);
    }

    @Override
    public CommonResult<PageResult<List<CouponRespDto>>> page(CouponPageReqDto couponPageReqDto) {
        Page<Object> page = PageHelper.startPage(couponPageReqDto.getCurrentPage(), couponPageReqDto.getPageSize());
        List<Coupon> couponList = couponMapper.page(couponPageReqDto);

        List<CouponRespDto> couponRespDtoList = getCouponRespDtoList(couponList);
        PageResult<List<CouponRespDto>> listPageResult = PageResult.setData((int) page.getTotal(), page.getPageSize(), page.getPages(), page.getPageNum(), couponRespDtoList);
        return CommonResult.success(listPageResult);
    }

    private static List<CouponRespDto> getCouponRespDtoList(List<Coupon> couponList) {
        List<CouponRespDto> couponRespDtoList = new ArrayList<>();
        for (Coupon coupon : couponList) {
            CouponRespDto couponRespDto = new CouponRespDto();
            BeanUtils.copyProperties(coupon, couponRespDto);

            couponRespDto.setPeriodUnitStr(CouponPeriodUnitEnum.getDescByUnit(coupon.getPeriodUnit()));
            couponRespDto.setUseTypeStr(CouponUseTypeEnum.getDescByType(coupon.getUseType()));

            couponRespDtoList.add(couponRespDto);
        }
        return couponRespDtoList;
    }

    @Override
    public CommonResult<CouponRespDto> findById(Integer id) {
        RBucket<Coupon> bucket = redissonClient.getBucket(RedisConstantPre.COUPON_CONDITION_PRE + id);
        Coupon coupon = bucket.get();
        if (coupon == null) {
            coupon = couponMapper.selectByPrimaryKey(id);
            if (coupon == null) {
                //防止缓存穿透，存放一个空对象
                bucket.set(new Coupon());
                log.error("优惠券id={} 不存在",id);
                return CommonResult.failed(ResultCode.PARAMETER_ERROR);
            }
        }
        //防止缓存穿透
        if (coupon.getId() == null) {
            log.error("缓存穿透 优惠券id={} 不存在",id);
            return CommonResult.failed(ResultCode.PARAMETER_ERROR);
        }
        CouponRespDto couponRespDto = new CouponRespDto();
        BeanUtils.copyProperties(coupon, couponRespDto);
        couponRespDto.setPeriodUnitStr(CouponPeriodUnitEnum.getDescByUnit(coupon.getPeriodUnit()));
        couponRespDto.setUseTypeStr(CouponUseTypeEnum.getDescByType(coupon.getUseType()));
        return CommonResult.success(couponRespDto);
    }

    @Override
    public CommonResult<List<CouponRespDto>> findByIdList(List<Integer> idList) {
         return CommonResult.success(getCouponRespDtoList(couponMapper.selectByIdList(idList)));
    }

    @Override
    public CommonResult<Boolean> checkCoupon(List<Integer> idList) {
        List<Coupon> couponList = couponMapper.selectByIdList(idList);
        for (Coupon coupon : couponList) {
            if (coupon.getOverlay() == CouponOverlayEnum.UN_OVERLAY.getOverlay()) {
                return CommonResult.failed(ResultCode.COUPON_OVERLAY);
            }
            if (coupon.getStatus() == CouponTypeEnum.USED.getStatus()) {
                return CommonResult.failed(ResultCode.COUPON_USED);
            }
            if (coupon.getStatus() == CouponTypeEnum.EXPIRED.getStatus()) {
                return CommonResult.failed(ResultCode.COUPON_EXPIRED);
            }
        }
        return null;
    }
}
